<script setup lang="ts">

import { nextTick, onMounted, ref, watch } from "vue";
import { Delete } from "@element-plus/icons-vue";
import SvgIcon from "../utils/SvgIcon.vue";
import { invoke } from "@tauri-apps/api/core";
import { connect, disconnect, listen, send } from "@kuyoonjo/tauri-plugin-tcp";
import { ElMessage } from "element-plus";

const rows = ref()
const sendMode = ref('ASCII')
const ipAddress = ref()
const port = ref(8888)
const server = ref()
const times = ref(10)
const timeShow = ref(false)
const inputValue = ref('')
const chatView = ref([])
const scrollHeight = ref()
const scroll = ref()
const connectState = ref(false)
let clientId = 'unique-client-id'
let clientListen = undefined

watch(chatView,
    async () => {
        if (Math.ceil(parseInt(scrollHeight.value.replace('px', '')) / 21) <= chatView.value.length) {
            await nextTick()
            scroll.value.setScrollTop(parseInt(scrollHeight.value.replace('px', '')) + 42)
        }
    }, { deep: true })

window.addEventListener('resize', () => {
    const element = document.getElementsByClassName('card-send')[0]
    rows.value = Math.floor((element.clientHeight - 80) / 20)
    const height = document.getElementsByClassName('serial-card-body')[0].clientHeight
    scrollHeight.value = `${height - 95}px`
})

onMounted(async () => {
    ipAddress.value = await invoke("get_loacl_ip")
    const element = document.getElementsByClassName('card-send')[0]
    rows.value = Math.floor((element.clientHeight - 80) / 20)
    const height = document.getElementsByClassName('serial-card-body')[0].clientHeight
    scrollHeight.value = `${height - 95}px`
})

const connectServer = async () => {
    server.value = false
    if (connectState.value === false) {
        // 服务器没有开启
        await connect(clientId, `${ipAddress.value}:${port.value}`).then(async () => {
            ElMessage({
                message: '服务器连接成功',
                type: 'success'
            })
            server.value = true
            connectState.value = true
            clientListen = await listen(data => {
                if (data.payload.id === clientId && data.payload.event.message)
                    chatView.value.push({
                        mode: true,
                        message: new TextDecoder('utf-8').decode(new Uint8Array(data.payload.event.message.data)),
                        time: (new Date()).toLocaleString()
                    })
            })
            console.log(clientListen)
        }).catch((e) => {
            ElMessage({
                message: '服务器连接失败|' + e.message,
                type: 'error'
            })
            server.value = false
            connectState.value = false
            return
        })
    } else {
        // 服务器关闭
        await disconnect(clientId)
        connectState.value = false
        clientListen()
        clientListen = undefined
    }
}

const sendMessage = () => {
    if (connectState.value) {
        if (inputValue.value === '') {
            ElMessage({
                message: '请输入要发送的内容',
                type: 'warning'
            })
            return
        }
        send(clientId, inputValue.value).then(() => {
            chatView.value.push({
                mode: false,
                message: inputValue.value,
                time: (new Date()).toLocaleString()
            })
        }).catch((error) => {
            ElMessage({
                message: '发送失败！' + error,
                type: 'error'
            })
            connectState.value = false
            server.value = false
            clientListen()
            clientListen = undefined
        })

    } else {
        // 没有连接服务器
        ElMessage({
            message: '请先连接服务器',
            type: 'warning'
        })
    }
}
const checkChange = (value: any) => {
    timeShow.value = value
}

const clearReceive = () => {
    chatView.value = []
}

const saveReceive = () => {
    // TODO 在electron中使用文件保存
}

</script>

<template>
    <div style="height: 100%">
        <el-card class="serial-card" body-class="serial-card-body" style="height: 48%; position: relative"
            body-style="height: 100%; padding: 10px">
            <div style="margin-bottom: 10px; display: flex;
            justify-content: space-between;">
                <div>
                    <el-space style="margin-right: 15px">
                        <el-text>服务器地址:</el-text>
                        <el-input v-model="ipAddress" maxlength="15" style="width: 140px"></el-input>
                    </el-space>
                    <el-space style="gap: 0; margin-right: 15px">
                        <el-text>端口:</el-text>
                        <el-input v-model="port" style="width: 80px; margin-left: 15px"></el-input>
                    </el-space>
                    <el-switch @change="connectServer" style="--el-switch-on-color: #13ce66; margin-right: 15px"
                        v-model="server">
                    </el-switch>
                    <el-checkbox label="添加时间戳" @change="checkChange" />
                </div>
                <div>
                    <el-tooltip effect="dark" content="清空接收区" placement="top-start">
                        <el-button type="success" circle @click="clearReceive">
                            <el-icon>
                                <Delete />
                            </el-icon>
                        </el-button>
                    </el-tooltip>
                    <el-tooltip effect="dark" content="保存接收区" placement="top-start" @click="saveReceive">
                        <el-button type="warning" circle>
                            <el-icon>
                                <svg-icon name="save" />
                            </el-icon>
                        </el-button>
                    </el-tooltip>
                </div>
            </div>
            <el-card body-class="card-scroll" style="height: calc(100% - 60px)" body-style="height: 100%; padding: 5px">
                <el-scrollbar class="scroll" :height="scrollHeight" always ref="scroll">
                    <div v-for="item in chatView">
                        <div v-if="item.mode" style="text-align: start">
                            <el-text type="success" v-if="timeShow">{{ item.time }}: {{ item.message }}</el-text>
                            <el-text type="success" v-else>{{ item.message }}</el-text>
                        </div>
                        <div v-else style="text-align: end; margin: 2px 10px">
                            <el-text type="primary" v-if="timeShow">{{ item.time }}: {{ item.message }}</el-text>
                            <el-text type="primary" v-else>{{ item.message }}</el-text>
                        </div>
                    </div>
                </el-scrollbar>
            </el-card>
        </el-card>

        <el-card class="card-send" style="height: 52%">
            <!--     串口发送数据区域       -->
            <div style="margin-bottom: 10px">
                <el-radio-group v-model="sendMode">
                    <el-radio value="ASCII" size="small">ASCII</el-radio>
                    <el-radio value="HEX" size="small">HEX</el-radio>
                </el-radio-group>
                <el-divider direction="vertical" />
                <span style="margin-left: 10px">
                    <el-text>定时发送: </el-text>
                    <el-input-number v-model="times" controls-position="right" style="width: 100px">
                        <template #suffix>S</template>
                    </el-input-number>
                </span>
            </div>
            <el-row :gutter="3">
                <el-col :span="22">
                    <el-input v-model="inputValue" type="textarea" :rows="rows" :resize="'none'"></el-input>
                </el-col>
                <el-col :span="2" style="position: relative;">
                    <el-button class="send-bnt" style="top: 0" @click="inputValue = ''">清空</el-button>
                    <el-button class="send-bnt" style="bottom: 0" @click="sendMessage">发送</el-button>
                </el-col>
            </el-row>
        </el-card>
    </div>
</template>

<style scoped>
.serial-card {
    margin-bottom: 5px;
}

.send-bnt {
    width: 100%;
    margin: 0 5px;
    position: absolute;
}
</style>